/*Copyright 2014 Rajesh Putta http://www.codesnippets4all.com

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
* 
*/

package com.codesnippets4all.jthunder.extension.plugins.input.excel;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import com.codesnippets4all.jthunder.core.IPlugin;
import com.codesnippets4all.jthunder.core.exceptions.AutomationException;
import com.codesnippets4all.jthunder.core.execution.IStatus;
import com.codesnippets4all.jthunder.core.execution.Status;
import com.codesnippets4all.jthunder.core.execution.StatusType;
import com.codesnippets4all.jthunder.core.execution.status.AutomationStatusManager;
import com.codesnippets4all.jthunder.core.state.IContext;

public class ExcelReaderPlugin implements IPlugin {

	public IStatus process(Map<String, String> configuration, IContext context,AutomationStatusManager statusManager) {
		
		String filePath=configuration.get("filepath");
		
		if(filePath==null || filePath.trim().equals(""))
			throw new AutomationException("ExcelReaderPlugin requires filepath to be configured in automation config file...");
		

		BufferedInputStream bufferedStream=null;

		List<Sheet> sheets=new ArrayList<Sheet>();
		
		StatusType status=null;
		
		try{
			bufferedStream=new BufferedInputStream(new FileInputStream(filePath));

			if(filePath.endsWith(".xls"))
			{
				readOLEbasedExcel(bufferedStream, sheets);
			}
			else
			{
				readXmlBasedExcel(bufferedStream, sheets);
			}
			
			status=StatusType.SUCCESS;
			
		}catch (Exception e) {
			status=StatusType.EXCEPTION;
		}

		IStatus finalStatus=new Status(status, sheets);
		
		return finalStatus;
	}
	
	
	@SuppressWarnings("rawtypes")
	private void readOLEbasedExcel(BufferedInputStream bufferedStream, List<Sheet> sheets) throws IOException
	{
		HSSFWorkbook workbook=new HSSFWorkbook(bufferedStream);
		
		int sheetCount=workbook.getNumberOfSheets();
		
		for(int index=0;index<sheetCount;index++)
		{
			HSSFSheet sheet=workbook.getSheetAt(index);
			
			Sheet s=new Sheet();
			
			sheets.add(s);
			
			int lastRowNumber=sheet.getLastRowNum();
			
			for(int rowIndex=0;rowIndex<lastRowNumber;rowIndex++)
			{
				HSSFRow row=sheet.getRow(rowIndex);
				
				Record record=new Record();
				
				s.addRecord(record);
				
				Iterator it=row.cellIterator();
				
				while(it.hasNext())
				{
					record.addCellValue(it.next());
				}
			}
		}
		
	}
	
	@SuppressWarnings("rawtypes")
	private void readXmlBasedExcel(BufferedInputStream bufferedStream, List<Sheet> sheets) throws IOException
	{
		XSSFWorkbook workbook=new XSSFWorkbook(bufferedStream);
		
		int sheetCount=workbook.getNumberOfSheets();
		
		for(int index=0;index<sheetCount;index++)
		{
			XSSFSheet sheet=workbook.getSheetAt(index);
			
			Sheet s=new Sheet();
			
			sheets.add(s);
			
			int lastRowNumber=sheet.getLastRowNum();
			
			for(int rowIndex=0;rowIndex<lastRowNumber;rowIndex++)
			{
				XSSFRow row=sheet.getRow(rowIndex);
				
				Record record=new Record();
				
				s.addRecord(record);
				
				Iterator it=row.cellIterator();
				
				while(it.hasNext())
				{
					record.addCellValue(it.next());
				}
			}
		}
		
	}
}
